import BackBtn from '@components/globalComponents/BackBtn';
import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import Stats from 'three/examples/jsm/libs/stats.module';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

function XBotGLB2(): React.ReactElement {
  // 模型容器引用，用于挂载Three.js场景
  const mountRef = useRef<HTMLDivElement>(null);
  let scene: any;
  let renderer: any;
  let camera: any;
  let model; // 模型引用，用于存储加载的模型
  let skeleton; // 骨骼引用，用于存储模型骨架
  let mixer; // 动画混合器，用于播放模型动画
  let clock; // 时钟，用于更新动画
  let panelSettings;
  let numAnimations: number;
  let stats: any;

  const allActions = [];

  // 动画状态
  const baseActions: any = {
    idle: { weight: 1 },
    walk: { weight: 0 },
    run: { weight: 0 },
  };
  const additiveActions: any = {
    sneak_pose: { weight: 0 },
    sad_pose: { weight: 0 },
    agree: { weight: 0 },
    headShake: { weight: 0 },
  };

  function activateAction(action: any) {
    const clip = action.getClip();
    const settings = baseActions[clip.name] || additiveActions[clip.name];
    setWeight(action, settings.weight);
    action.play();
  }

  function setWeight(action: any, weight: any) {
    action.enabled = true;
    action.setEffectiveTimeScale(1);
    action.setEffectiveWeight(weight);
  }

  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);
  }
  const init = () => {
    // 创建场景
    scene = new THREE.Scene();
    const currentMount: any = mountRef.current;

    scene.background = new THREE.Color(0xa0a0a0);
    // 添加雾效，使场景看起来更真实
    scene.fog = new THREE.Fog(0xa0a0a0, 10, 500);
    // 添加半球光
    const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3);
    hemiLight.position.set(0, 20, 0);
    scene.add(hemiLight);

    // 添加平行光: 用于模拟太阳光的效果
    const dirLight = new THREE.DirectionalLight(0xffffff, 3);
    dirLight.position.set(3, 10, 10);
    scene.add(dirLight);
    dirLight.castShadow = true; // 开启阴影投射
    // 配置阴影投射的参数
    dirLight.shadow.camera.near = 0.1;
    dirLight.shadow.camera.far = 40;
    dirLight.shadow.camera.left = -2;
    dirLight.shadow.camera.right = 2;
    dirLight.shadow.camera.top = 2;
    dirLight.shadow.camera.bottom = -2;
    scene.add(dirLight);

    // 创建一个平面
    const mesh = new THREE.Mesh(
      new THREE.PlaneGeometry(100, 100), // 平面的宽度和高度
      new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }),
    ); // 平面的材质，设置为不写入深度缓冲区，避免遮挡
    mesh.rotation.x = -Math.PI / 2; // 旋转平面，使其垂直于场景
    mesh.receiveShadow = true; // 接收阴影
    scene.add(mesh);

    const loader = new GLTFLoader();
    renderer = new THREE.WebGLRenderer({ antialias: true });

    loader.load('http://127.0.0.1:9981/robot/xbot.glb', (gltf) => {
      model = gltf.scene; // 获取模型
      scene.add(model); // 将模型添加到场景中
      // 遍历模型中的所有对象，设置阴影投射
      model.traverse((object: any) => {
        if (object.isMesh) {
          object.castShadow = true;
        }
      });
      // 提取模型的骨骼结构----骨骼结构是从3d glb 文件中获取的吗？
      // 是，从3d glb 文件中获取的骨骼结构，用于动画播放
      skeleton = new THREE.SkeletonHelper(model);
      skeleton.visible = true; // 显示骨骼辅助线
      scene.add(skeleton); // 将骨骼辅助线添加到场景中

      const animation = gltf.animations;
      mixer = new THREE.AnimationMixer(model);

      numAnimations = animation.length; // 动画数量

      for (let i = 0; i !== numAnimations; i++) {
        let clip: any = animation[i]; // 获取动画片段
        const { name } = clip; // 获取动画片段的名称

        if (baseActions[name]) {
          const action = mixer.clipAction(clip);
          activateAction(action);
          baseActions[name].action = action;
          allActions.push(action);
        } else if (additiveActions[name]) {
          THREE.AnimationUtils.makeClipAdditive(clip);
          if (clip.name.endsWith('_pose')) {
            clip = THREE.AnimationUtils.subclip(clip, clip.name, 2, 3, 30);
          }
          const action = mixer.clipAction(clip);
          activateAction(action);
          additiveActions[name].action = action;
          allActions.push(action);
        }
      }
      createPanel();
      renderer.setAnimationLoop({ antialias: true });
    });

    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    currentMount.appendChild(renderer.domElement);

    // 创建相机
    camera = new THREE.PerspectiveCamera(
      45,
      window.innerWidth / window.innerHeight,
      1,
      100,
    );
    camera.position.set(-1, 2, 3);

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enablePan = false;
    controls.enableZoom = false;
    controls.target.set(0, 1, 0);
    controls.update();

    stats = new Stats();
    currentMount.appendChild(stats.dom);

    window.addEventListener('resize', onWindowResize);
  };
  useEffect(() => {
    if (!mountRef.current) return;
    init();
  }, []);
  return (
    <div>
      {/* 返回首页按钮 */}
      <div
        style={{ position: 'absolute', top: '16px', left: '16px', zIndex: 10 }}
      >
        <BackBtn />
      </div>
      <div className="xbot-glb-container">
        {/* 模型容器 */}
        <div ref={mountRef} style={{ width: '100%', height: '100vh' }} />
      </div>
    </div>
  );
}

export default XBotGLB2;
